<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>selection-checkbox</title>
    <link rel="stylesheet" href="css/stylecss.css">
</head>

<body>
    <div class="box">

        <ul>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
            <li>
                <input type="checkbox" name="checkbox" id="">
            </li>
        </ul>
    </div>
    <div id="mouseMove"
        style="position: absolute;width: 0px;height: 0px;border: 1px dashed #000;display: none;left: -1px;right: -1px;">
    </div>
</body>
<script>
    var count = 0;
    var mouseArea = document.getElementById("mouseMove")
    var startPoint = null;
    // var endPoint = null;

    // 监听鼠标在页面上按下
    document.onmousedown = function (event) {
        count = 1;
        mouseArea.style.display = "block";
        // console.log("mouse down");
        startPoint = {
            x: event.pageX,
            y: event.pageY
        }
        // console.log("x: ", event.pageX, ", y: ", event.pageY);
    }

    // 监听鼠标在页面上移动
    document.onmousemove = function (event) {
        if (count == 1) {
            endPoint = {
                x: event.pageX,
                y: event.pageY
            }
            var area = calcMouseArea(startPoint, endPoint)
            if (area != null) {
                changeSelectedCheck(area)
                mouseArea.style.left = area.x + "px"
                mouseArea.style.top = area.y + "px"
                mouseArea.style.width = area.w + "px"
                mouseArea.style.height = area.h + "px"
                // console.log("mouse info: ", JSON.stringify(area))
            }
            // console.log("mouse move");
        }
    }

    // 监听鼠标在页面上抬起
    document.onmouseup = function (event) {
        count = 0;
        mouseArea.style.display = "none";
        startPoint = null;
        mouseArea.style.left = "0px"
        mouseArea.style.top = "0px"
        mouseArea.style.width = "0px"
        mouseArea.style.height = "0px"
        // endPoint = null;
        // console.log("mouse up");
    }

    // 计算鼠标选择的区域起始点，大小
    var calcMouseArea = function (posX, posY) {
        if (posX == null || posX == null) {
            return null
        }
        var pos = {}
        if (posX.x < posY.x) {
            pos.x = posX.x
            pos.w = posY.x - posX.x
        } else {
            pos.x = posY.x
            pos.w = posX.x - posY.x
        }
        if (posX.y < posY.y) {
            pos.y = posX.y
            pos.h = posY.y - posX.y
        } else {
            pos.y = posY.y
            pos.h = posX.y - posY.y
        }
        return pos
    }
    // 获取页面需要控制的check标签
    var checkList = document.querySelectorAll(".box input[type='checkbox']")
    // 对鼠标所选择的区域做样式调整
    var changeSelectedCheck = function (pos) {
        var startPoints = calcEdegPoints(pos.x, pos.y, pos.w, pos.h)
        var domWidth = checkList[0].offsetWidth
        var domHeight = checkList[0].offsetHeight
        checkList.forEach(element => {
            element.checked = false
            if (isExistInSelectedArea(element, startPoints, domWidth, domHeight)) {
                element.checked = true
            }
        });
    }

    // 判断元素是否在所选择区域
    var isExistInSelectedArea = function(dom, startPoints, domWidth, domHeight) {
        var domPos = getElementPos(dom)
        var domPoints = calcEdegPoints(domPos.x, domPos.y, domWidth, domHeight)
        // console.log("domPoints info: ", domPoints);
        // console.log("startPoints info: ", startPoints);
        // return
        if (domPoints.x1.x >= startPoints.x1.x && domPoints.x1.x <= startPoints.x2.x) {
            if (domPoints.x1.y >= startPoints.x1.y && domPoints.x1.y <= startPoints.x3.y) {
                return true
            }
        }
        if (domPoints.x2.x >= startPoints.x1.x && domPoints.x2.x <= startPoints.x2.x){
            if (domPoints.x2.y >= startPoints.x1.y && domPoints.x2.y <= startPoints.x3.y) {
                return true
            }
        }
        if (domPoints.x3.x >= startPoints.x1.x && domPoints.x3.x <= startPoints.x2.x) {
            if (domPoints.x3.y >= startPoints.x1.y && domPoints.x3.y <= startPoints.x3.y) {
                console.log(1)
                return true
            }
        }
        if (domPoints.x4.x >= startPoints.x1.x && domPoints.x4.x <= startPoints.x2.x) {
            if (domPoints.x4.y >= startPoints.x1.y && domPoints.x4.y <= startPoints.x3.y) {
                return true
            }
        }
        return false
    }

    // 计算元素相对于页面的绝对位置
    function getElementPos(el) {
        var ua = navigator.userAgent.toLowerCase();
        var isOpera = (ua.indexOf('opera') != -1);
        var isIE = (ua.indexOf('msie') != -1 && !isOpera); // not opera spoof
        // var el = document.getElementById(elementId);
        if (el.parentNode === null || el.style.display == 'none') {
            return false;
        }
        var parent = null;
        var pos = [];
        var box;
        if (el.getBoundingClientRect) {
            //IE
            box = el.getBoundingClientRect();

            var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);

            var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);

            return { x: box.left + scrollLeft, y: box.top + scrollTop };

        } else if (document.getBoxObjectFor) {
            // gecko
            box = document.getBoxObjectFor(el);
            var borderLeft = (el.style.borderLeftWidth) ? parseInt(el.style.borderLeftWidth) : 0;
            var borderTop = (el.style.borderTopWidth) ? parseInt(el.style.borderTopWidth) : 0;
            pos = [box.x - borderLeft, box.y - borderTop];
        } else {
            // safari & opera
            pos = [el.offsetLeft, el.offsetTop];
            parent = el.offsetParent;
            if (parent != el) {
                while (parent) {
                    pos[0] += parent.offsetLeft;
                    pos[1] += parent.offsetTop;
                    parent = parent.offsetParent;
                }
            }
            if (ua.indexOf('opera') != -1 || (ua.indexOf('safari') != -1 && el.style.position == 'absolute')) {
                pos[0] -= document.body.offsetLeft;
                pos[1] -= document.body.offsetTop;
            }
        }
        if (el.parentNode) {
            parent = el.parentNode;
        }
        else {
            parent = null;
        }
        while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') { // account for any scrolled ancestors
            pos[0] -= parent.scrollLeft;
            pos[1] -= parent.scrollTop;
            if (parent.parentNode) {
                parent = parent.parentNode;
            }
            else {
                parent = null;
            }
        }
        return { x: pos[0], y: pos[1] };
    }
    
    // 计算出dom元素的四个边界点
    var calcEdegPoints = function(x, y, w, h) {
        return points = {
            x1: {
                x: x,
                y: y,
            },
            x2: {
                x: x + w,
                y: y,
            },
            x3: {
                x: x,
                y: y + h,
            },
            x4: {
                x: x + w,
                y: y + h
            }
        }
    }
</script>

</html>